package ext.tianma.bom.workflow;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;

import wt.doc.WTDocument;
import wt.epm.EPMDocument;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.WTObject;
import wt.fc.collections.WTArrayList;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.State;
import wt.part.WTPart;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartUsageLink;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.type.ClientTypedUtility;
import wt.util.WTException;
import wt.vc.wip.WorkInProgressHelper;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfState;
import wt.workflow.work.WfAssignedActivity;

import com.ptc.core.meta.common.TypeIdentifier;

import ext.com.iba.IBAUtil;
import ext.com.workflow.WorkflowUtil;
import ext.tianma.project.relatedproduct.CreateProjectBusiness;
import ext.tianma.supplier.SupplierInfoQueryBusiness;
import ext.tianma.version.ComToolUtil;


/**Description:【BOM审核确认流程】的业务处理逻辑
 * @author    :  YangWen
 * @create at :  2013-8-22   下午5:01:53
 */
public class ExamineAndApproveConfirmBusiness  implements BOMWorkFlowInterface  {
	
	/**
	 * 展示是否输出log信息
	 */
	private static boolean isShow = true;
	    
	 /**
     * 图档类文档：com.tianma.pdmtest.DrawingDoc
     * 特定的【文档】业务对象名称 
     */
    private static final String DRAWINGDOC = SingletonBOM.getInstance().getDrawingDoc();
    
    /**
     * 原材料
     */    
    private static final String RAWMATERIAL = SingletonBOM.getInstance().getRawMaterial();
    
    /**
     * 半成品
     */    
    private static final String SEMIFINISHEDGOOD = SingletonBOM.getInstance().getSemiFinishedGood(); 
    
    /**
     * 第一个生命周期状态数组：正在工作、重新工作
     */
    private static final String[] FIRSTLIFESTATEARRAY = { "INWORK","REWORK" };
    /**
     * 第三个生命周期状态数组（包含多个状态）：正在工作，正在审阅，重新工作
     */
    private static final String[] THIRDLIFESTATEARRAY = { "INWORK", "UNDERREVIEW", "REWORK" };
        
    /**
     * 某个工作流模板的名称：样品承认及批准流程
     */
    public static final String WORKFLOWTEMPLATENAME = "样品承认及批准流程";
    /**
     * 二级物料:com.tianma.pdmtest.TwoLevelMaterial
     * 特定的【部件】业务对象名称 
     */
    private static final String TWOLEVELMATERIAL = SingletonBOM.getInstance().getTwoLevelMaterial();  
   
        
	
	/**
	 * 私有构造函数，防止实例化
	 */
	private ExamineAndApproveConfirmBusiness(){
		
	}
	

	/**输出log信息
	 * @param info
	 */
	private static void out(String info){
		if(isShow)
			System.out.println("【BOM审核确认流程】的业务处理逻辑:"+ExamineAndApproveConfirmBusiness.class.getName()+":"+info);
	}
	
	/**YW
     * 判断指定对象是否属于fullType对象或者其子对象
     * @param obj WTObject对象
     * @param fullType 内部全程，如wt.doc.WTDocument|com.tianma.pdmtest.DrawingDoc
     * @return 如果是，则返回true
     * @throws WTException 
     */
    public static boolean isSubObject(WTObject obj , String fullType) throws WTException{
    	
    	if(ComToolUtil.isEmpty(obj)||ComToolUtil.isEmpty(fullType))
    		return false;
    		    	
    	String innerName = getInnerFullName(obj);
    	if(ComToolUtil.isEmpty(innerName))
    		return false;
    	
    	Hashtable<String , String> subTypeName = getAllSubTypeInnerFullName(fullType);	
    	if(subTypeName == null || subTypeName.size() == 0)
    		return false;	    	
    	
      	Iterator<String> iterator = subTypeName.keySet().iterator();					
    	while(iterator.hasNext()){
    		String key = (String) iterator.next();
    		String value = (String) subTypeName.get(key);
    		if (value.trim().equals(innerName.trim())) 
    		    return true;    		
    	}
    	
    	return false;
    }
    
    
    public static WTPart showTianmaInfo(WTPart part) throws WTException{
    	if(ComToolUtil.isEmpty(part))
    		return null;
    	
    	
    	 	
    	LifeCycleManaged lcm = (LifeCycleManaged)part;	
    	String currentState = lcm.getState().toString();
		out("当前对象【"+part.getDisplayIdentifier()+"】的生命周期是："+currentState);
		
		//新建物料
		if(currentState.equals("NewPart")){	
			return part;
		}
		
		//半成品或者原材料 （正在审阅） 列出来   
		if(currentState.equals("UNDERREVIEW")){		
				//是【原材料】或者【半成品】	    	
		    	if(isSubObject(part, RAWMATERIAL)||isSubObject(part, SEMIFINISHEDGOOD))
		    		return part;
		}
		
		//正在工作的需要走承认的 列出来；
		if(currentState.equals("INWORK")){			
		  	Object obj = null;
	    	try {
				obj = IBAUtil.getIBAValue(part, "partRecognize");
			} catch (RemoteException e) {
				e.printStackTrace();
			}	    			    	
	    	out("partRecognize属性值为:"+obj);
	    	if(ComToolUtil.isEmpty(obj)){
	    	   return null;
	    	}else{
	    		String flag = obj.toString().trim();
	    		out("partRecognize的类型是Boolean类型.");
	    		if(flag.equalsIgnoreCase("true") || flag.equalsIgnoreCase("是") || flag.equalsIgnoreCase("Y"))
	    			return part;
	    	}			
		}
		
    	return null;
    }
	

    /**YW
     * 获取指定部件下满足如下要求的所有部件集合
     * 1、此部件所关联的进程模板中含有【样品承认及批准流程】模板；
     * 2、此进程正在运行
     * @param partOid 部件的oid值
     * @return ArrayList<WTPart>
     * @throws WTException
     */
    @SuppressWarnings("deprecation")
	public static ArrayList<WTPart> getAllPartsOfRunningSpecificProcess(String partOid) throws WTException {
    	
    	if(ComToolUtil.isEmpty(partOid))
    		return null;
    	
    	Persistable persistable = SupplierInfoQueryBusiness.getPersistableFromOid(partOid);		
		if(persistable == null)
			return null;
		
		out("传入的【对象】是："+persistable.getIdentity());
    	
		ArrayList<WTPart> result = new ArrayList<WTPart>();
		
		
		
		
		if(persistable instanceof WTPart){
		
	    	WTPart partObj = (WTPart)persistable;
	    	
	    	//获得部件的所有子部件，不包含传入部件本身
	    	ArrayList<WTPart> allSubPart = getAllSubPart(partObj);    			
	    						
		    for (WTPart part : allSubPart) {
		    	
		    	WTPart tm = showTianmaInfo(part);
		    	if(tm!=null){
		    		result.add(tm);
		    		continue;
		    	}
		    	
		    	//1、	是【原材料】对象		    	
		    	if(!isSubObject(part, RAWMATERIAL))
		    		continue;
		    	
		    	//2、	partRecognize属性值为是；
		    	Object obj = null;
		    	try {
					obj = IBAUtil.getIBAValue(part, "partRecognize");
				} catch (RemoteException e) {
					e.printStackTrace();
				}
		    			    	
		    	out("partRecognize属性值为:"+obj);
		    	if(ComToolUtil.isEmpty(obj)){
		    		out("partRecognize的值为空！");
		    		continue;
		    	}else{
		    		String flag = obj.toString().trim();
		    		out("partRecognize的类型是Boolean类型.");
		    		if(!(flag.equalsIgnoreCase("true") || flag.equalsIgnoreCase("是") || flag.equalsIgnoreCase("Y")))
		    			continue;
		    	}
		    	
		    	//3，【BOM审核】活动时，生命周期状态时【正在工作/正在审阅/重新工作】
		    	LifeCycleManaged lcm = (LifeCycleManaged)part;		    	
								
		    	WfProcess currentProcess = WorkflowUtil.getProcess(partObj);		    	
		    	WfAssignedActivity submitActivity = getDesignatedActivity(currentProcess,"BOM提交");
		    			    		
		    	if(submitActivity != null && submitActivity.isComplete()){
		    		if (!isInner(lcm, THIRDLIFESTATEARRAY)) {
		    			continue;
		    		}
		    	}else{
			    	//3、	生命周期状态时正在审阅；
		    		//获取当前对象的生命周期状态
					String currentState = lcm.getState().toString();
					out("当前对象【"+part.getDisplayIdentifier()+"】的生命周期是："+currentState);
					if(!(currentState.equals("UNDERREVIEW")))
						continue;
		    	}
		    	
		    	//4、	关联的流程是【样品承认及批准流程】流程				    	
		    	//获取部件所关联的所有进程
				ArrayList<WfProcess> referenceProcessList = getRreferenceProcess(part);
				//如果不存在任务进程
				if(referenceProcessList == null || referenceProcessList.size() == 0)
					continue;
				for (WfProcess process : referenceProcessList) {
					//如果进程正在运行并且工作流模板是【样品承认及批准流程】，则是需要给客户提示信息的部件
				    if (process.getState().equals(WfState.OPEN_RUNNING) && WORKFLOWTEMPLATENAME.equals(process.getTemplate().getName())) {
				    	result.add(part);
				    	break;
				    }
				}
								
		    }
		}
		
		else if(persistable instanceof WTDocument){
			WTDocument doc = (WTDocument) persistable;
			
		    //获取当前文档所关联的所有零部件
		    QueryResult refPartQR = ext.com.core.CoreUtil.getAssociatedParts(doc);
		    if(refPartQR == null || refPartQR.size() == 0)
		    	out("传入进来的对象【"+doc.getDisplayIdentifier()+"】所关联的部件个数是：0");
		    else
		    	out("传入进来的对象【"+doc.getDisplayIdentifier()+"】所关联的部件个数是："+refPartQR.size());
		    
		    while (refPartQR.hasMoreElements()) {
				Object refObj = refPartQR.nextElement();
				if (refObj instanceof WTPart) {
				    WTPart partObj = (WTPart) refObj;
				    
				    out("当前处理的对象是："+partObj.getDisplayIdentifier());
				
				  //获得部件的所有子部件，不包含传入部件本身
			    	ArrayList<WTPart> allSubPart = getAllSubPart(partObj);   
			    	allSubPart.add(partObj);
			    	out("对象【"+partObj.getDisplayIdentifier()+"】所关联的部件个数(包含其本身)是："+allSubPart.size());
								    						
				    for (WTPart part : allSubPart) {
				    	
				    	WTPart tm = showTianmaInfo(part);
				    	if(tm!=null){
				    		result.add(tm);
				    		continue;
				    	}
				    	
				    	
				    	//1、	是【原材料】对象		    	
				    	if(!isSubObject(part, RAWMATERIAL))
				    		continue;
				    	
				    	//2、	partRecognize属性值为是；
				    	Object obj = null;
				    	try {
							obj = IBAUtil.getIBAValue(part, "partRecognize");
						} catch (RemoteException e) {
							e.printStackTrace();
						}
				    			    	
				    	out("partRecognize属性值为:"+obj);
				    	if(ComToolUtil.isEmpty(obj)){
				    		out("partRecognize的值为空！");
				    		continue;
				    	}else{
				    		String flag = obj.toString().trim();
				    		out("partRecognize的类型是Boolean类型.");
				    		if(!(flag.equalsIgnoreCase("true") || flag.equalsIgnoreCase("是") || flag.equalsIgnoreCase("Y")))
				    			continue;
				    	}
				    	
				    					    	
				    	LifeCycleManaged lcm = (LifeCycleManaged)part;	
				    	//生命周期状态时正在审阅；
			    		//获取当前对象的生命周期状态
						String currentState = lcm.getState().toString();												
						out("当前对象【"+part.getDisplayIdentifier()+"】的生命周期是："+currentState);
						
						//3、如果生命周期状态是【新品】，则直接添加，直接跳过此次循环
						if(currentState.equals("NewProduct")){
							result.add(part);
							continue;
						}
						
						//3，生命周期状态时 正在审阅 且 关联的流程是【样品承认及批准流程】流程
				    	if(!(currentState.equals("UNDERREVIEW")))
							continue;
												
				    	//4、	关联的流程是【样品承认及批准流程】流程				    	
				    	//获取部件所关联的所有进程
						ArrayList<WfProcess> referenceProcessList = getRreferenceProcess(part);
						//如果不存在任务进程
						if(referenceProcessList == null || referenceProcessList.size() == 0)
							continue;
						for (WfProcess process : referenceProcessList) {
							//如果进程正在运行并且工作流模板是【样品承认及批准流程】，则是需要给客户提示信息的部件
						    if (process.getState().equals(WfState.OPEN_RUNNING) && WORKFLOWTEMPLATENAME.equals(process.getTemplate().getName())) {
						    	result.add(part);
						    	break;
						    }
						}
				    	
				    	
				    }
				    
				}
		    }
		}
	   			
		return result;
    }
	
    
    /**YW
     * 从指定的进程里获得指定名称的活动对象
     * @param process WfProcess，指定的进程
     * @param activityName String，进程中某个活动的名称
     * @return WfAssignedActivity 某个活动对象
     * @throws WTException
     */
    public static WfAssignedActivity getDesignatedActivity(WfProcess process, String activityName) throws WTException {
    	
    	if(ComToolUtil.isEmpty(process)||ComToolUtil.isEmpty(activityName))
    		return null;
    	    	
	    QueryResult qr = process.getContainerNodes();
	    while (qr.hasMoreElements()) {
			Object obj = qr.nextElement();
			if (obj instanceof WfAssignedActivity) {
			    WfAssignedActivity activity = (WfAssignedActivity) obj;
			    if (activityName.equals(activity.getName().trim())) {
					return activity;
			    }
			}
	    }
    	
    	return null;
     }
    

 
    /**YW
     * 检查BOM当前步骤需满足的业务要求
     * @param pbo WTObject对象，即主业务对象
     * @param erpObjs WTArrayList对象,即随签对象
     * @throws WTException 
     */
    public static WTArrayList checkBomPassCondition(WTObject pbo , WTArrayList erpObjs) throws WTException {
    	
    	if(ComToolUtil.isEmpty(pbo) || !(pbo instanceof WTPart))
    		return null;
    	
    	WTPart part = (WTPart)pbo;
    	
    	//递归获得所有的子部件
    	ArrayList<WTPart> allSubPart = getAllSubPart(part);
    	out("指定部件【"+part.getDisplayIdentifier()+"】下包含的所有子部件个数是："+allSubPart.size());
    	
    	//存放满足如下要求的部件的编号，需最后抛出错误信息
		//该部件关联了不是【样品承认及批准流程】模板的进程，且此进程处于【正在运行】状态
		ArrayList<String> notSampleWFList = new ArrayList<String>();
		
		//获得随签对象
		//即获得指定部件下所有子部件，满足如下要求的【部件】以及其相关的【EPM文档】及【图档类文档】
    	ArrayList<WTObject> result = new ArrayList<WTObject>();
    	
    	
		//保存被检出部件的编号
		ArrayList<String> checkoutPartNumberList = new ArrayList<String>();
	
	   
	    for (WTPart onePart : allSubPart) {
	    	
	    	
	    	
	    	//把如下加到随签列表里，不做报错
	    	
	    	//1、	不是二级物料
	    	//如果【当前部件类型】是【二级物料】或者其第一级子类型，则直接跳过	    	
			if (isSubObject(onePart, TWOLEVELMATERIAL)) 
				continue;
			
			
			out("此对象【"+onePart+"】的生命周期是："+((LifeCycleManaged)onePart).getState().toString().trim());
			
	    	//2、	正在工作  、重新工作
			//加入随签列表；同时将关联的CAD文档、图档类文档（图档类文档："+prefix+".DrawingDoc须包括其子类型）加入随签列表。
			 //如果当前对象的【生命周期状态】为【正在工作】，【重新工作】
		    if (isInner(onePart, FIRSTLIFESTATEARRAY)) {
				//添加【当前部件】对象
				result.add(onePart);
				//收集与【当前部件】相关的所有【EPM文档】及【图档类文档】
				result.addAll(getReferenceEPMDocAndSpecificDoc(onePart));
		    }
		    
	    }
	    
	    
	    
	    if (!notSampleWFList.isEmpty()) {
	    	String notSample = "";
	    	for(String number : notSampleWFList)
	    		notSample += "\n" + number;
	    	throw new WTException("以下部件编号关联了不是【样品承认及批准流程】模板的进程，且此进程处于【正在运行】状态:"+notSample);
	    }
	    
	    
	    for (WTObject obj : result) {
	    	if(obj == null || !(obj instanceof WTPart))
	    		continue;
	    		    	
	    	if(WorkInProgressHelper.isCheckedOut((WTPart)obj)){
			    checkoutPartNumberList.add(((WTPart)obj).getNumber());
			}
	    }
	    
	    if (!checkoutPartNumberList.isEmpty()) {
	    	String checkoutPart = "";
	    	for(String number : checkoutPartNumberList)
	    		checkoutPart += "\n" + number;
	    	throw new WTException("以下部件编号被检出："+checkoutPart);
	    }	    
		
	    //清空erpObjs变量，之后将PBO和随签子件加入到erpObjs变量中
	    out("清空随签对象前，其内所含对象个数为："+erpObjs.size());
	    erpObjs.clear();
	    out("清空随签对象后，其内所含对象个数为："+erpObjs.size());
	    erpObjs.add(part);
	    out("往随签对象里添加了pbo对象："+part.getDisplayIdentifier());
	    out("result 的个数是："+result.size());
	    erpObjs.addAll(result);
	    out("随签对象里的对象个数是："+erpObjs.size());
	    return erpObjs;
    }
    
    
    
    /**YW
     * 设置pbo和所有随签对象的生命周期状态为目标状态
     * @param pbo WTObject对象，即主业务对象
     * @param erpObjs WTArrayList，即随签对象集合
     * @param targetState String ，即目标生命周期状态 ，
		UNDERREVIEW.value=正在审阅
		REWORK.value=重新工作
		NewProduct.value=新品
     * @throws WTException 
     */
	public static void setLifeCycleState(WTObject pbo, WTArrayList erpObjs, String targetState) throws WTException {
    	
		if(ComToolUtil.isEmpty(pbo) ||!(pbo instanceof WTPart)|| ComToolUtil.isEmpty(targetState))
			return ;
				
		out("目标生命周期状态的英文名是："+targetState);
			
		//处理pbo的生命周期状态
		WTPart pboPart = (WTPart) pbo;
		String pboState = pboPart.getLifeCycleState().toString();
		out("当前pbo对象【"+pboPart.getDisplayIdentifier()+"】的生命周期状态是："+pboState);
		if (!pboState.equalsIgnoreCase(targetState)) {
			out("正在处理pbo对象【"+pboPart.getDisplayIdentifier()+"】的生命周期状态...");
			try {
				LifeCycleHelper.service.setLifeCycleState(pboPart, State.toState(targetState));
			} catch (WTException e) {					
				e.printStackTrace();
				throw new WTException("给当前的pbo对象设置生命周期状态时报错:\n" +
						"可能是当前对象【"+pboPart.getDisplayIdentifier()+"】没有【"+State.toState(targetState).getLocalizedMessage(Locale.CHINA)+"】这个状态，程序终止！");		
			}
		}
		out("处理完当前pbo对象的生命周期状态后，当前pbo对象【"+pboPart.getDisplayIdentifier()+"】的生命周期状态是："+pboPart.getLifeCycleState().toString());
		
		//处理随签对象里所有对象的生命周期状态
		setLifeCycleState(erpObjs,targetState);	    		
    }
    
    
    
    
    /**YW
     * 设置所有随签对象的生命周期状态为目标状态
     * @param erpObjs WTArrayList，即随签对象集合
     * @param targetState String ，即目标生命周期状态 ，
		UNDERREVIEW.value=正在审阅
		REWORK.value=重新工作
		NewProduct.value=新品
     * @throws WTException 
     */
    @SuppressWarnings("deprecation")
	public static void setLifeCycleState(WTArrayList erpObjs, String targetState) throws WTException {
    	
		if(ComToolUtil.isEmpty(targetState))
			return ;
		
		if(erpObjs == null)
			out("随签对象里所含对象为空");
		else
			out("随签对象里所含对象个数是："+erpObjs.size());
		
		out("目标生命周期状态的英文名是："+targetState);
					
		if(erpObjs!=null && erpObjs.size() > 0){
			for(int i=0;i<erpObjs.size();++i){
				Object obj = null;
				try {
					obj = erpObjs.getPersistable(i);
				} catch (WTException e) {
					e.printStackTrace();
					throw new WTException("从随签对象里获取第"+(i+1)+"个值时出错，程序终止！");						
				}
				if (obj instanceof LifeCycleManaged) {
				    LifeCycleManaged lcm = (LifeCycleManaged) obj;
				    String currentlcmState = lcm.getLifeCycleState().toString();
				    out("欲处理的对象【"+lcm.getIdentity()+"】的当前生命周期状态是："+currentlcmState);
				    if (!currentlcmState.equalsIgnoreCase(targetState)) {
				    	out("正在处理对象【"+lcm.getIdentity()+"】的生命周期状态...");
				    	try {
							LifeCycleHelper.service.setLifeCycleState(lcm, State.toState(targetState));
						}  catch (WTException e) {
							e.printStackTrace();
							throw new WTException("给当前的pbo对象设置生命周期状态时报错:\n" +
									"可能是当前对象【"+lcm.getIdentity()+"】没有【"+State.toState(targetState).getLocalizedMessage(Locale.CHINA)+"】这个状态，程序终止！");									
						}				    	
				    }
				    out("处理完后，对象【"+lcm.getIdentity()+"】的生命周期状态是："+lcm.getLifeCycleState().toString());
				}
		    }
		}
		
	    		
    }
    
    
    
    
    
    
    
    
    
    
    
    
    /**判断传入的进程集合是否不存在【正在运行】的进程
     * @param processList 进程集合
     * @return boolean 如果不存在，则返回true，否则返回false
     */
    public static boolean notExistRunning(ArrayList<WfProcess> processList){
    	if(processList == null || processList.size() == 0)
    		return false;
    	
    	for(WfProcess process : processList){
    		if(process.getState().equals(WfState.OPEN_RUNNING))
    			return false;
    	}
    	
    	return true;
    }
    
    
    
    
    
    
    
    
    
    
	
    /**YW
     * 递归获取指定部件下的所有部件
     * @param part WTPart对象
     * @return ArrayList<WTPart>对象
     */
    public static ArrayList<WTPart> getAllSubPart(WTPart part) {
		ArrayList<WTPart> result = new ArrayList<WTPart>();
		if (part != null) {
		    try {
		    	//获得部件所关联的所有部件
				QueryResult allLink = WTPartHelper.service.getUsesWTPartMasters(part);
								
				while (allLink.hasMoreElements()) {
				    WTPartUsageLink link = (WTPartUsageLink) allLink.nextElement();
				    WTPart subPart = (WTPart) CreateProjectBusiness.getLatestWTPartByMaster((WTPartMaster) link.getUses());
				    result.add(subPart);
				    result.addAll(getAllSubPart(subPart));
				}
		    } catch (Exception e) {
		    	e.printStackTrace();
		    }
		}
		return result;
    }
    
    
    
	
    
    /**获取指定对象相关的所有进程
     * @param obj WTObject对象
     * @return ArrayList<WfProcess>对象
     * @throws WTException
     */
    public static ArrayList<WfProcess> getRreferenceProcess(WTObject obj) throws WTException {
		ArrayList<WfProcess> result = new ArrayList<WfProcess>();
		QueryResult processQR = queryRreferenceProcess(obj);
		while (processQR.hasMoreElements()) {
		    Object process = processQR.nextElement();
		    result.add((WfProcess) process);
		}
		return result;
    }
	

    /**获取指定对象相关的所有进程
     * @param obj WTObject对象
     * @return QueryResult对象，即进程的集合
     * @throws WTException
     */
    @SuppressWarnings("deprecation")
	private static QueryResult queryRreferenceProcess(WTObject obj) throws WTException {
    	if(obj == null)
    		return null;
		ReferenceFactory factory = new ReferenceFactory();
		String ref = factory.getReferenceString(obj);
		QuerySpec processQS = new QuerySpec(WfProcess.class);
		SearchCondition sc = new SearchCondition(WfProcess.class, "businessObjReference", "=", ref);
		processQS.appendSearchCondition(sc);	
		return PersistenceHelper.manager.find(processQS);
    }
    
    
    /**YW
     * 获取部件下所关联的所有【EPM文档】和【图档类文档】类型的文档
     * @param part WTPart对象
     * @return ArrayList<WTObject>
     * @throws WTException
     */
    private static ArrayList<WTObject> getReferenceEPMDocAndSpecificDoc(WTPart part) throws WTException {
    	if(part == null)
    		return null;
		ArrayList<WTObject> result = new ArrayList<WTObject>();
		
		//获取部件中的所有【EPM文档】对象		
		QueryResult epmQR = ext.com.core.CoreUtil.getAssociatedCADDocuments(part);
		if(epmQR == null || epmQR.size() == 0)
			out("此部件【"+part.getDisplayIdentifier()+"】所关联的【EPM文档】数量是  0  个!");
		else
			out("此部件【"+part.getDisplayIdentifier()+"】所关联的【EPM文档】数量是  "+epmQR.size()+"   个!");
		
		while (epmQR.hasMoreElements()) {
		    Object epmDoc = epmQR.nextElement();
		    if (epmDoc instanceof EPMDocument) {
		    	result.add((EPMDocument) epmDoc);
		    }
		}
		
		//获取指定部件下所关联的所有【图档类文档】类型的文档
		result.addAll(getReferencrDoc(DRAWINGDOC, part));
		return result;
    }
    

    /**YW
     * 获得部件中【"说明方"文档】中的所有【图档类文档】类型的文档
     * @param docType 【图档类文档】的内部全名
     * @param part 指定的部件
     * @return
     * @throws WTException
     */
    private static HashSet<WTDocument> getReferencrDoc(String docType, WTPart part) throws WTException {
    	
    	if(ComToolUtil.isEmpty(part) || ComToolUtil.isEmpty(docType))
    		return null;
    	
    	Hashtable<String , String> subTypeName = getAllSubTypeInnerFullName(docType);	
    	if(subTypeName == null || subTypeName.size() == 0)
    		return null;
    	
		HashSet<WTDocument> result = new HashSet<WTDocument>();
		
		//获取部件中的所有【"说明方"文档】对象		
		QueryResult docQR = ext.com.core.CoreUtil.getAssociatedDescribeDocuments(part);
		if(docQR == null || docQR.size() == 0)
			out("此部件【"+part.getDisplayIdentifier()+"】所关联的【\"说明方\"文档】数量是  0  个!");
		else
			out("此部件【"+part.getDisplayIdentifier()+"】所关联的【\"说明方\"文档】数量是  "+docQR.size()+"   个!");
		
		while (docQR.hasMoreElements()) {
		    Object docObj = docQR.nextElement();
		    if (docObj instanceof WTDocument) {
		    	WTDocument doc = (WTDocument)docObj;		    	
		    	String innerName = getInnerFullName(doc);
		    	
		    	Iterator<String> iterator = subTypeName.keySet().iterator();					
				while(iterator.hasNext()){
					String key = (String) iterator.next();
					String value = (String) subTypeName.get(key);
					out(key+" --- > "+value);
					if (value.trim().equals(innerName.trim())) {
					    result.add((WTDocument) docObj);
					    break;
					}
				}
		    	
		    }
		}
		
		return result;
    }
    
    
    /**YW
     * 获得指定对象的内部全名
     * @param obj 指定的WTObject
     * @return String 如wt.doc.WTDocument|com.tianma.pdmtest.DrawingDoc|com.tianma.pdmtest.DesignDoc
     * @throws WTException
     */
    public static String getInnerFullName(WTObject obj) throws WTException {
  		if (ComToolUtil.isEmpty(obj))
  		    return null;
  		
  		TypeIdentifier typeIdentifier = ClientTypedUtility.getTypeIdentifier(obj);  		
  		return typeIdentifier.getTypename();
    }
  
    
    
    
    /**YW
	 * 获得指定内部全称下的所有子类型(包括当前对象本身)，如果当前类型下包含子类，则只返回当前一个对象类型
	 * @param parentInnerFullName String，指定的一个拥有子类型的全称
	 * 如wt.doc.WTDocument|com.tianma.pdmtest.DrawingDoc
	 * @return Hashtable<String , String>对象，【子类型的中文名称，子类型的全部英文字段】
	 * @throws WTException 
	 */
	public static Hashtable<String , String> getAllSubTypeInnerFullName(String parentInnerFullName) throws WTException {
		
		if(ComToolUtil.isEmpty(parentInnerFullName))
			return null;
		
		Hashtable<String , String> result = new Hashtable<String, String>();
		
		Locale locale = Locale.CHINA;
		
		//通过英文字段全称获取相应的类型标识对象
		TypeIdentifier parentTypeId = com.ptc.core.foundation.type.server.impl.TypeHelper.getTypeIdentifier(parentInnerFullName);		
		if(parentTypeId == null)
			return null;
		out("通过【"+parentInnerFullName+"】此值，无法找到相应的类型标识对象，可能此值不是全称内部名称，直接返回空!");
		
		Set<TypeIdentifier> set=com.ptc.core.htmlcomp.util.TypeHelper.getSubTypesForType(parentTypeId,locale);
		//一般情况下，此情况是不会出现的，如非是系统的bug，因为系统返回的值里面已经包含了父类型值
        if(set == null || set.size() == 0){
        	out("通过【"+parentInnerFullName+"】此值，可以找到相应的类型标识对象，但是它下面不含任何子类型!");        	
        	String parentTypeShowName=com.ptc.core.foundation.type.server.impl.TypeHelper.getLocalizedTypeString(parentTypeId, locale);
			String parentTypeInnerName=parentTypeId.getTypename();
			result.put(parentTypeShowName, parentTypeInnerName);
        	return result;
        }
        		
		Iterator<TypeIdentifier> iterator = set.iterator();
        
        //子类型的中文名称
        String subTypeShowName=null;
        //子类型的所对应的英文全称
        String subTypeInnerName=null;
                
        while(iterator.hasNext()) {
        	TypeIdentifier subTypeId = (TypeIdentifier)iterator.next();
        	subTypeShowName=com.ptc.core.foundation.type.server.impl.TypeHelper.getLocalizedTypeString(subTypeId, locale);
			subTypeInnerName=subTypeId.getTypename();
			
			out("子类型的名称："+subTypeShowName +",所对应于的英文名称为："+subTypeInnerName);
			
			//添加【子类型的中文名称，子类型的全部英文字段】
			//【设计图纸, wt.doc.WTDocument|com.tianma.pdmtest.DrawingDoc|com.tianma.pdmtest.DesignDoc】				
			result.put(subTypeShowName, subTypeInnerName);							
		}		
		
		return result;
	}
    
    /**YW
     * 判断指定对象是否是objClss类型的
     * @param obj WTObject对象
     * @param objClass 业务对象的名称
     * @return 如果是则返回true，否则返回false
     * @throws WTException
     */
    public static boolean isObjectType(WTObject obj, String objClass) throws WTException {
		if (ComToolUtil.isEmpty(obj) || ComToolUtil.isEmpty(objClass))
		    return false;
		
		TypeIdentifier typeIdentifier = ClientTypedUtility.getTypeIdentifier(obj);
		String objClassFullName = typeIdentifier.getTypename();
		if (objClassFullName.endsWith(objClass)) 
		    return true;
		
		return false;
    }
    
    /**YW
     * 判断指定对象的生命周期状态是否在指定的状态数组里
     * @param lcm LifeCycleManaged对象
     * @param states 生命周期状态数组
     * @return 如果包含在内，则返回true，否则false
     */
    public static boolean isInner(LifeCycleManaged lcm, String[] states) {
    	if(ComToolUtil.isEmpty(lcm) || ComToolUtil.isEmpty(states) || states.length == 0)
    		return false;
    	
		//获取当前对象的生命周期状态
		String currentState = lcm.getState().toString();
		for (String state : states) {
		    if (state.equals(currentState)) 
		    	return true;		    
		}
		
		return false;
    }
    
   
    
    
}
